package com.sww.pj.sys.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sww.pj.common.annotation.RequiredLog;
import com.sww.pj.common.exception.ServiceException;
import com.sww.pj.common.pojo.PageObject;
import com.sww.pj.common.utils.AssertUtils;
import com.sww.pj.sys.dao.RoleMenuDao;
import com.sww.pj.sys.dao.SysMenuDao;
import com.sww.pj.sys.dao.SysUserDao;
import com.sww.pj.sys.dao.SysUserRoleDao;
import com.sww.pj.sys.pojo.SysUser;

import com.sww.pj.sys.service.SysUserService;

@Service
public class SysUserServiceImpl implements SysUserService {

	@Autowired
	private SysUserDao sysUserDao;

	@Autowired
	private SysUserRoleDao sysUserRoleDao;
	

	//把数据库里的信息，放到页面上，并做分页查询
	@Override
	@RequiresPermissions("sww:user:find")
	@RequiredLog("查询本社区用户")
	public PageObject<SysUser> findPageObjects( String username,Long pageCurrent) {
		//1.验证参数合法性
		//1.1验证pageCurrent的合法性，
		//不合法抛出IllegalArgumentException异常
		if(pageCurrent==null||pageCurrent<1)
			throw new IllegalArgumentException("当前页码不正确");
		//2.基于条件查询总记录数
		//2.1) 执行查询
		long rowCount=sysUserDao.getRowCount(username);
		//2.2) 验证查询结果，假如结果为0不再执行如下操作
		if(rowCount==0)
			throw new ServiceException("系统没有查到对应记录");
		//3.基于条件查询当前页记录(pageSize定义为2)
		//3.1)定义pageSize
		int pageSize=10;
		//3.2)计算startIndex
		Long startIndex=(long) ((pageCurrent-1)*pageSize);
		//3.3)执行当前数据的查询操作
		List<SysUser> records=
				sysUserDao.findPageObjects(username, startIndex, pageSize);
		//4.对分页信息以及当前页记录进行封装
		//4.1)构建PageObject对象
		PageObject<SysUser> pageObject=new PageObject<>();
		//4.2)封装数据
		pageObject.setPageCurrent(pageCurrent);
		pageObject.setPageSize(pageSize);
		pageObject.setRowCount(rowCount);
		pageObject.setRecords(records);
		pageObject.setPageCount((rowCount-1)/pageSize+1);
		//5.返回封装结果。
		return pageObject;
	}

	//删除操作
	@Override
	@RequiresPermissions("sww:user:delete")
	@RequiredLog("删除本社区用户")
	public int deleteObjects(Integer... ids) {
		if(ids==null||ids.length==0)
			throw new IllegalArgumentException("请输入id的值");
		int rows=sysUserDao.deleteObjects(ids);
		if(rows==0)
			throw new ServiceException("记录可能已经不存在");
		return rows;
	}

	//添加用户操作
	@Override
	@RequiresPermissions("sww:user:add")
	@RequiredLog("添加本社区用户")
	public int saveObjects(SysUser entity, Integer[] roleIds) {
		//1.参数校验
		AssertUtils.isArgValid(entity==null, "保存对象不能为空");
		AssertUtils.isArgValid(entity.getUsername()==null||"".equals(entity.getUsername()), "用户名不能为空");
		AssertUtils.isArgValid(entity.getPassword()==null||"".equals(entity.getPassword()), "密码不能为空");
		AssertUtils.isArgValid(roleIds==null||roleIds.length==0, "必须为用户分配角色");
		//2.保存用户自身信息
		//2.1 构建salt(盐)值
		String salt=UUID.randomUUID().toString();//产生一个固定长度随机字符串
		//2.2 基于相关API对密码进行加密
		//借助spring框架中自带API对密码进行加密
		//String hashedPassword=
		//DigestUtils.md5DigestAsHex((salt+entity.getPassword()).getBytes());
		//借助shiro框架中的API对密码进行加密
		SimpleHash sh=new SimpleHash("MD5",//算法名称
				entity.getPassword(), //未加密的密码
				salt,//加密盐 
				1);//这里1表示加密次数
		String hashedPassword=sh.toHex();//将加密结果转换为16进制的字符串
		entity.setSalt(salt);//为什么盐值也要保存到数据库?(登录时还要使用此salt对登录密码进行加密)
		entity.setPassword(hashedPassword);
		//2.3 将用户信息写入到数据库
		int rows=sysUserDao.insertObjects(entity);

		//3.保存用户与角色关系数据
		sysUserRoleDao.insertObjects(entity.getId(), roleIds);
		return rows;

	}

	//修改操作
	@Override
	@RequiresPermissions("sww:user:update")
	@RequiredLog("修改本社区用户")
	public int updateObjects(SysUser entity, Integer[] roleIds) {
		//1.参数校验
		AssertUtils.isArgValid(entity==null, "保存对象不能为空");
		AssertUtils.isArgValid(entity.getUsername()==null||"".equals(entity.getUsername()), "用户名不能为空");
		AssertUtils.isArgValid(roleIds==null||roleIds.length==0, "必须为用户分配角色");
		//2.保存用户自身信息
		int rows=sysUserDao.updateObjects(entity);
		AssertUtils.isServiceValid(rows==0, "记录可能已经不存在了");
		//3.保存用户与角色关系数据
		sysUserRoleDao.deleteObjectsByUserId(entity.getId());
		sysUserRoleDao.insertObjects(entity.getId(), roleIds);
		return rows;
	}

	//修改的那个查询
	@Override
	public Map<String, Object> findObjectByIds(Integer id) {

		//long t1=System.currentTimeMillis();//直接在类方法中添加代码会违背开闭原则
		//1.参数校验
		AssertUtils.isArgValid(id==null||id<1,"id值无效");
		//2.查询用户以及用户对应的部门信息
		SysUser user=sysUserDao.findObjectByIds(id);
		AssertUtils.isServiceValid(user==null, "记录可能已经不存在");
		//3.查询用户对应的角色信息
		List<Integer> roleIds=sysUserRoleDao.findRoleIdsByUserId(id);
		//4.封装查询结果
		Map<String,Object> map=new HashMap<>();
		map.put("user", user);
		map.put("roleIds", roleIds);
		//long t2=System.currentTimeMillis();
		//log.info("time {}",t2-t1);
		return map;
	}



}
